Denoで2 つめの拡張機能のtutorialをやってみ
2022-01-29
コピペしただけ
相対パスの先頭に./を付け足した
03:00:07 iconを加える
Githubから直接downloadして用意する
あ、tutorialとは違って、dark theme対応されているようだ
あと96pxがなくてかわりに32pxが用意されている
03:02:32 iconのパスをmanifest.jsonに反映した
03:03:17 popupを作る
ツールバーのボタンを押すと表示されるUI
JSではなくTSで作ってみる
03:06:58 コードを書く
さーて、こっからが問題だ
きちんと型付けできるかどうか
コード先頭に以下を記入した
code:ts
/// <reference no-default-lib="true" />
/// <reference lib="esnext" />
/// <reference lib="dom" />
03:12:53 型エラー発生
code:ts
return browser.extension.getURL("beasts/frog.jpg");
browser.extensionにgetURLが存在しない?
MDNを見てみる
tutorialが古いままだった、ということか
03:16:14 直った!
03:27:32 refactoring中
Promise chainをasync-awaitに書き直している
top-level awaitを使ってもいいだろう
htmlでmoduleとして読み込めばいい
03:28:37 event listenerで定義する必要のない函数を外に出す
03:29:16 event objectに型をつける
code:ts
document.addEventListener("click", (e) => {
/**
* アクティブなタブを取得し、
* "beastify()" か "reset()" を適切に呼び出す
*/
if (e.target.classList.contains("beast")) {
browser.tabs.query({ active: true, currentWindow: true })
.then(beastify)
.catch(reportError);
} else if (e.target.classList.contains("reset")) {
browser.tabs.query({ active: true, currentWindow: true })
.then(reset)
.catch(reportError);
}
});
このままだとtargetがEventTarget | nullと推論されてしまう
今回はdiv.resetかdiv.beast以外で発生したclick eventを全て無視するので、そのように型ガードを書く
03:39:39 tabs[0].idの型解決
今回は関係なさそうだから、!で型判定を飛ばしちゃってもいいかな?
content scriptが読み込まれたタブを取得したいのだから
code:ts
const tabs = await browser.tabs.query({
active: true,
currentWindow: true,
});
code:ts
type PickRequired<T, K extends keyof T> =
& T
& {
};
function ensureTabId(
tab: browser.Tabs.Tab,
): asserts tab is PickRequired<browser.Tabs.Tab, "id"> {
if (tab.id !== undefined) return;
throw TypeError("The value must has id.");
}
04:03:42 全ての型エラーを消した
04:29:40 作った
04:32:19 beasts/に画像を入れた
04:33:50 あとはbuildするだけ
うーん、最初から拡張機能のdirectory構成を作るより、build段階で作ってzipにしてしまうほうが便利な気がする
書き換えよう
types.tsに型定義と型ガードを入れる
code:tree
beastify/
build.ts
src/
beastify.ts
popup.ts
popup.html
popup.css
deps.ts
types.ts
assets/
icons/
beasts/
04:46:02 できた
次はbuild.tsを作る
minifyはしなくていいや
05:02:37 JSZipでdirectory構成を作る 05:27:28 できた
05:27:33 拡張機能を試す
05:33:40 バグつぶし
パスをミスってた
build.tsで定数を置換するときに、文字列を""で囲むのを失念していた
05:37:20 おかしいな。画像が読み込まれないぞ
拡張機能のアイコンは読み込まれている
画像はbrowserにちゃんと取り込めている
一時的な拡張機能のURLから開けた
beastify.jsは読み込めているのだろうか?
popup.jsは動いている
htmlもCSSも読めている
クリックもできる
CSSの挿入もされている
05:45:48 debuggingできない?
popupを開いている間はdevelopper toolにhtmlが表示される
しかしdevelopper toolにfocusを移した途端にhtmlが消え失せてしまう
これではbreak pointも設置できない
consoleには何も表示されないし。
どうなってんだい
06:01:13 popup.jsをESModuleにしたことは関係ないみたい
Classicにしても変わらなかった
06:05:03 やはりconsole.log()が動いていない
何故か何も表示されない
一旦chromeで試してみるか
firefoxとは挙動が変わるかもしれない
06:09:44 chromeで開いたら、beastify.jsが読み込まれていないというエラーがHTMLにでてきた
firefoxでは出なかった
firefoxだとエラーを出さないのか?
console.logもちゃんとでてた
06:11:37 あー、相対パスでbeastify.jsを指定したせいだ
Chromeでdebugしたらちゃんと情報をconsoleに表示してくれた
変数の追跡もできたし
MDNにbackgroundからはこの関数を使用できないと明確に書かれていた……
Note: This function is only useful in contexts where there is a browser tab, such as an options page.
If you call it from a background script or a popup, it will return undefined.
popup.jsもbackground扱いになるんだな
リストにないファイルだと言われる
./beasts/snake.jpgじゃだめなのか?
beasts/snake.jpgだとどうなるか試してみよう
06:28:53 やった!読み込まれた
……結局./beasts/snake.jpgとbeasts/snake.jpgの違いは何だったのだろうか
iconsとかは問題なかったのに……
これ地雷だろtakker.icon
絶対パスだとどうだ?
06:31:31 絶対パスでも問題ないようだ
06:31:57 firefoxでも改めて試してみる
06:36:14 うまく行った
firefoxとchromeとの挙動の違いが気になるな
chromeだと、表示した画像分resetを押さないと画面がもとに戻らなかった
今回は気にしないことにする
相変わらずconsole.logは全く出力されない……
潰したバグとは関係なかったようだ
もしかしてfirefoxの仕様?
もうこれ罠だろ
06:50:17 popup.tsをESModuleに戻す
06:52:37 問題なく動いた
06:52:43 tutorial終了
githubに保存しておく
07:03:53 保存した